//
//  KMNetworkClient.m
//  CashLoans
//
//  Created by KM on 2017/12/14.
//  Copyright © 2017年 KM. All rights reserved.
//

#import "KMNetworkClient.h"
#import "XDNetworkHelper.h"

#define kErrmsg @"errorMsg"

#define kErrBase @"errorBase"

@implementation KMNetworkClient


/**
 GET请求 无缓存
 
 @param URL 请求地址
 @param parameters 请求参数
 @return 信号
 */
+(RACSignal *)GET:(NSString *)URL
       parameters:(id)parameters {
    [MBProgressHUD ln_showProgressHUD:@""];
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        NSURLSessionTask *sessionTask = [KMNetworkHelper GET:URL parameters:parameters success:^(NSURLSessionTask *task, id responseObject) {
            [MBProgressHUD ln_hideHUD];
            BaseResponseModel *base = [BaseResponseModel modelWithJSON:responseObject];
            if ([responseObject[@"status"] integerValue] ==500)
            {
                [MBProgressHUD ln_showTips:responseObject[@"message"]];
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            } else if ([self isCorrectResponse:base]) {
                [subscriber sendNext:responseObject];
                [subscriber sendCompleted];
            }else if (base.code == 0) {
                [subscriber sendCompleted];
                NSString *msg = base.msg ? base.msg : @"登录已过期，请重新登录";
                [MBProgressHUD ln_showTips:msg];
//                DispatchAsyncOnMainThread(^{
//                  //  KMPostNotification(kLogoutNotificationName);
//                });
            } else {
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            }
        } failure:^(NSError *error) {
            [subscriber sendError:error];
            [MBProgressHUD ln_hideHUD];
        }];
        
        return [RACDisposable disposableWithBlock:^{
            [sessionTask cancel];
        }];
    }];
}

/**
 XDGET请求 无缓存

 @param URL 请求地址
 @param parameters 请求参数
 @return 信号
 */
+(RACSignal *)XDGET:(NSString *)URL
       parameters:(id)parameters {
    [MBProgressHUD ln_showProgressHUD:@""];
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {

        NSURLSessionTask *sessionTask = [XDNetworkHelper GET:URL parameters:parameters success:^(NSURLSessionTask *task, id responseObject) {
            [MBProgressHUD ln_hideHUD];
            BaseResponseModel *base = [BaseResponseModel modelWithJSON:responseObject];
            if ([responseObject[@"status"] integerValue] ==500)
            {
                [MBProgressHUD ln_showTips:responseObject[@"message"]];
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            } else if ([self isCorrectResponse:base]) {
                [subscriber sendNext:responseObject];
                [subscriber sendCompleted];
            }else if (base.code == 0) {
                [subscriber sendCompleted];
                NSString *msg = base.msg ? base.msg : @"登录已过期，请重新登录";
                [MBProgressHUD ln_showTips:msg];
                //                DispatchAsyncOnMainThread(^{
                //                  //  KMPostNotification(kLogoutNotificationName);
                //                });
            } else {
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            }
        } failure:^(NSError *error) {
            [MBProgressHUD ln_hideHUD];
            [subscriber sendError:error];
        }];

        return [RACDisposable disposableWithBlock:^{
            [sessionTask cancel];
        }];
    }];
}

/**
 fir.im 更新GET

 @param URL 请求地址
 @param parameters 请求参数
 @return 信号
 */
+(RACSignal *)firm_GET:(NSString *)URL
       parameters:(id)parameters {
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {

        NSURLSessionTask *sessionTask = [KMNetworkHelper GET:URL parameters:parameters success:^(NSURLSessionTask *task, id responseObject) {

            [subscriber sendNext:responseObject];
            [subscriber sendCompleted];

        } failure:^(NSError *error) {
            [subscriber sendError:error];
        }];

        return [RACDisposable disposableWithBlock:^{
            [sessionTask cancel];
        }];
    }];
}

/**
 GET请求 带缓存
 
 @param URL 请求地址
 @param parameters 请求参数
 @return 信号
 */
+(RACSignal *)GETWithCatch:(NSString *)URL
                parameters:(id)parameters {
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSURLSessionTask *sessionTask = [KMNetworkHelper GET:URL parameters:parameters responseCache:^(id responseCache) {
            [subscriber sendNext:responseCache];
        } success:^(NSURLSessionTask *task, id responseObject) {
            BaseResponseModel *base = [BaseResponseModel modelWithJSON:responseObject];
            if ([self isCorrectResponse:base]) {
                [subscriber sendNext:base.data];
                [subscriber sendCompleted];
            }else if (base.code == 0) {
                [subscriber sendCompleted];
                NSString *msg = base.msg ? base.msg : @"登录已过期，请重新登录";
                [MBProgressHUD ln_showTips:msg];
//                DispatchAsyncOnMainThread(^{
//                    //KMPostNotification(kLogoutNotificationName);
//                });
            }else {
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            }
        } failure:^(NSError *error) {
            [subscriber sendError:error];
        }];
        return [RACDisposable disposableWithBlock:^{
            [sessionTask cancel];
        }];
    }];
}

/**
 POST请求 无缓存
 
 @param URL 请求地址
 @param parameters 请求参数
 @return 信号
 */
+(RACSignal *) POST:(NSString *)URL
        parameters:(id)parameters {
    [MBProgressHUD ln_showProgressHUD:@""];
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSURLSessionTask *sessionTask = [KMNetworkHelper POST:URL parameters:parameters success:^(NSURLSessionTask *task, id responseObject) {
            [MBProgressHUD ln_hideHUD];
            BaseResponseModel *base = [BaseResponseModel modelWithJSON:responseObject];
            if ([responseObject[@"status"]integerValue] ==500)
            {
                [MBProgressHUD ln_showTips:responseObject[@"message"]];
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            } else if ([self isCorrectResponse:base]) {
                [subscriber sendNext:responseObject];
                [subscriber sendCompleted];
            }else if (base.code == -1) {
                [subscriber sendCompleted];
                NSString *msg = base.msg;
                [MBProgressHUD ln_showTips:msg];
            
            }
            else if (base.code == -99) {
                NSString *msg = base.msg ? base.msg : @"登录已过期，请重新登录";
                [MBProgressHUD ln_showTips:msg];
//                DispatchAsyncOnMainThread(^{
//                    [LNNotificationCenter postNotificationName:LNSwitchLoginControllerNotification object:nil];
//                });
            }
            else if (base.code == -98) {
                NSString *msg = base.msg ? base.msg : @"请进行C1认证";
                [MBProgressHUD ln_showTips:msg];
//                DispatchAsyncOnMainThread(^{
//                    [LNNotificationCenter postNotificationName:LNSC1VerifyControllerNotification object:nil];
//                });
            }
            else if (base.code == -97) {
                NSString *msg = base.msg ? base.msg : @"请进行C2认证";
                [MBProgressHUD ln_showTips:msg];
//                DispatchAsyncOnMainThread(^{
//                    [LNNotificationCenter postNotificationName:LNSC2VerifyControllerNotification object:nil];
//                });
            }
            else {
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            }

        } failure:^(NSError *error) {
            [MBProgressHUD ln_hideHUD];
            [MBProgressHUD ln_showErrorTips:error];
            [subscriber sendError:error];
        }];
        return [RACDisposable disposableWithBlock:^{
            [sessionTask cancel];
        }];
    }];
}

/**
 POST请求 带缓存
 
 @param URL 请求地址
 @param parameters 请求参数
 @return 信号
 */
+(RACSignal *)POSTWithCatch:(NSString *)URL
                 parameters:(id)parameters {
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        if ([parameters isKindOfClass:[NSDictionary class]]) {
            NSString *sha1String = [self sortedParameter: parameters];
            if (sha1String) {
                [KMNetworkHelper setValue:sha1String forHTTPHeaderField:@"sign"];
//                if (KMUserDefault.token) {
//                    [KMNetworkHelper setValue:KMUserDefault.token forHTTPHeaderField:@"token"];
//                }
            }
        }
        
        NSURLSessionTask *sessionTask = [KMNetworkHelper POST:URL parameters:parameters responseCache:^(id responseCache) {
            BaseResponseModel *base = [BaseResponseModel modelWithJSON:responseCache];
            if ([self isCorrectResponse:base]) {
                [subscriber sendNext:base.data];
            }
        } success:^(NSURLSessionTask *task, id responseObject) {
            BaseResponseModel *base = [BaseResponseModel modelWithJSON:responseObject];
            if ([self isCorrectResponse:base]) {
                [subscriber sendNext:base.data];
                [subscriber sendCompleted];
            }else if (base.code == 0) {
                [subscriber sendCompleted];
                NSString *msg = base.msg ? base.msg : @"登录已过期，请重新登录";
                [MBProgressHUD ln_showTips:msg];
//                DispatchAsyncOnMainThread(^{
//                //    KMPostNotification(kLogoutNotificationName);
//                });
            }else {
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            }
        } failure:^(NSError *error) {
            [MBProgressHUD ln_showErrorTips:error];
            [subscriber sendError:error];
        }];
        return [RACDisposable disposableWithBlock:^{
            [sessionTask cancel];
        }];
    }];
}

+(BOOL)isCorrectResponse:(BaseResponseModel *)base {
    if (base && base.code == 1) {
        return YES;
    }
    return NO;
}

/** 组装错误 */
+(NSError *)errorWithDataTask:(NSURLSessionTask *)task
                     Response:(BaseResponseModel *)base {
    if (base) {
        NSDictionary *errInfo = @{kErrmsg : base.msg ? base.msg : @"",kErrBase : base};
        return [NSError errorWithDomain:task.originalRequest.URL.absoluteString code:1024 userInfo:errInfo];
    }else {
        NSDictionary *errInfo = @{kErrmsg : @"返回格式错误"};
        return [NSError errorWithDomain:task.originalRequest.URL.absoluteString code:9527 userInfo:errInfo];
    }
}
/**
 上传单/多张图片
 
 *  @param URL        请求地址
 *  @param parameters 请求参数
 *  @param name       图片对应服务器上的字段
 *  @param images     图片数组
 *  @param fileNames  图片文件名数组, 可以为nil, 数组内的文件名默认为当前日期时间"yyyyMMddHHmmss"
 *  @param imageScale 图片文件压缩比 范围 (0.f ~ 1.f)
 *  @param imageType  图片文件的类型,例:png、jpg(默认类型)....
 @return 信号
 */
+(RACSignal *)uploadImageWithURL:(NSString *)URL
                      parameters:(id)parameters
                            name:(NSString *)name
                          images:(NSArray<UIImage *> *)images
                       fileNames:(NSArray<NSString *> *)fileNames
                      imageScale:(CGFloat)imageScale
                       imageType:(NSString *)imageType {
    [MBProgressHUD ln_showProgressHUD:@""];
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSURLSessionTask *sessionTask = [KMNetworkHelper uploadImagesWithURL:URL
                                                                  parameters:parameters
                                                                        name:name
                                                                      images:images
                                                                   fileNames:fileNames
                                                                  imageScale:imageScale
                                                                   imageType:imageType
                                                                    progress:nil
                                                                     success:^(NSURLSessionTask *task, id responseObject) {
                                                                         [MBProgressHUD ln_hideHUD];
            BaseResponseModel *base = [BaseResponseModel modelWithJSON:responseObject];
            if ([self isCorrectResponse:base]) {
                [subscriber sendNext:base.data];
                [subscriber sendCompleted];
            }else {
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            }
        } failure:^(NSError *error) {
            [MBProgressHUD ln_hideHUD];
            [MBProgressHUD ln_showErrorTips:error];
            [subscriber sendError:error];
        }];
        return [RACDisposable disposableWithBlock:^{
            [sessionTask cancel];
        }];
    }];
}

/**
 上传文件
 
 @param URL 请求地址
 @param parameters 请求参数
 @param name 文件对应服务器上的字段
 @param filePath 文件本地的沙盒路径
 @return 信号
 */
+(RACSignal *)uploadFileWithURL:(NSString *)URL
                     parameters:(id)parameters
                           name:(NSString *)name
                       filePath:(NSString *)filePath {
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSURLSessionTask *sessionTask = [KMNetworkHelper uploadFileWithURL:URL parameters:parameters name:name filePath:filePath progress:nil success:^(NSURLSessionTask *task, id responseObject) {
            BaseResponseModel *base = [BaseResponseModel modelWithJSON:responseObject];
            if ([self isCorrectResponse:base]) {
                [subscriber sendNext:base.data];
                [subscriber sendCompleted];
            }else {
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            }
        } failure:^(NSError *error) {
            [MBProgressHUD ln_showErrorTips:error];
            [subscriber sendError:error];
        }];
        return [RACDisposable disposableWithBlock:^{
            [sessionTask cancel];
        }];
    }];
}
/**
 上传文件
 
 @param URL 请求地址
 @param parameters 请求参数
 @param name 文件对应服务器上的字段
 @param fileData 文件数据
 @return 信号
 */
+(RACSignal *)uploadFileWithURL:(NSString *)URL
                     parameters:(id)parameters
                           name:(NSString *)name
                       fileData:(NSData *)fileData {
    [MBProgressHUD ln_showProgressHUD:@""];
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSURLSessionTask *sessionTask = [XDNetworkHelper uploadFileWithURL:URL
                                                                parameters:parameters
                                                                      name:name
                                                                  fileData:fileData
                                                                  progress:nil
                                                                   success:^(NSURLSessionTask *task, id responseObject) {
                                                                       [MBProgressHUD ln_hideHUD];
            BaseResponseModel *base = [BaseResponseModel modelWithJSON:responseObject];
            if ([self isCorrectResponse:base]) {
                [subscriber sendNext:base.data];
                [subscriber sendCompleted];
            }else {
                [subscriber sendError:[self errorWithDataTask:task Response:base]];
            }
        } failure:^(NSError *error) {
            [MBProgressHUD ln_hideHUD];
            [MBProgressHUD ln_showErrorTips:error];
            [subscriber sendError:error];
        }];
        return [RACDisposable disposableWithBlock:^{
            [sessionTask cancel];
        }];
    }];
}

/**
 对字典(Key-Value)排序 区分大小写
 
 @param parameter 要排序的字典
 */
+ (NSString *)sortedParameter:(NSDictionary *)parameter{
    
//    if (KMUserDefault.tokenSecret == nil) {
//        return nil;
//    }
    
    
    //将所有的key放进数组
    NSArray *allKeyArray = [parameter allKeys];
    
    //序列化器对数组进行排序的block 返回值为排序后的数组
    NSArray *afterSortKeyArray = [allKeyArray sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id _Nonnull obj2) {
        /**
         In the compare: methods, the range argument specifies the
         subrange, rather than the whole, of the receiver to use in the
         comparison. The range is not applied to the search string.  For
         example, [@"AB" compare:@"ABC" options:0 range:NSMakeRange(0,1)]
         compares "A" to "ABC", not "A" to "A", and will return
         NSOrderedAscending. It is an error to specify a range that is
         outside of the receiver's bounds, and an exception may be raised.
         
         - (NSComparisonResult)compare:(NSString *)string;
         
         compare方法的比较原理为,依次比较当前字符串的第一个字母:
         如果不同,按照输出排序结果
         如果相同,依次比较当前字符串的下一个字母(这里是第二个)
         以此类推
         
         排序结果
         NSComparisonResult resuest = [obj1 compare:obj2];为从小到大,即升序;
         NSComparisonResult resuest = [obj2 compare:obj1];为从大到小,即降序;
         
         注意:compare方法是区分大小写的,即按照ASCII排序
         */
        //排序操作
        NSComparisonResult resuest = [obj1 compare:obj2];
        return resuest;
    }];
//    NSLog(@"afterSortKeyArray:%@",afterSortKeyArray);
    
    //通过排列的key值获取value
    
    
    NSMutableArray *keyValueArray = [NSMutableArray array];
    
    for (NSString *keyString in afterSortKeyArray) {
        NSString *valueString = [parameter objectForKey:keyString];
        
        if ([valueString isKindOfClass:[NSString class]] && [valueString isEqualToString:@""]) {
            continue;
        }
        [keyValueArray addObject:keyString];
        [keyValueArray addObject:valueString];
    }
    
    NSString * keyValueString = [keyValueArray componentsJoinedByString:@""];
    
    
    
    NSString *waitEncryptString = [@"1" stringByAppendingString:keyValueString];
    
//    NSLog(@"waitEncryptString: %@",waitEncryptString);
//
//    KMLog(@"sha1String = %@", [waitEncryptString sha1String]);
    
    return [waitEncryptString sha1String];
}


@end
